package com.ecoolex.discount.sales.core.service;

import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateCrtKey;
import java.util.Base64;
import java.util.Enumeration;

import javax.crypto.Cipher;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.ecoolex.discount.sales.core.properties.UnionPayUCSPProperties;
import com.ecoolex.discount.sales.core.properties.UnionPayUCSPProperties.Encrypt;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.exception.BizException;

/**
 * 银联签名，解密服务
 * @author stephenCao
 *
 */
@Service
@EnableConfigurationProperties(UnionPayUCSPProperties.class)
public class UnionPayService {

	@Autowired
	UnionPayUCSPProperties unionPayUCSPProperties;
	
	public static final String X509 = "X.509";
	
	/**
	 * 银联云闪付验签
	 * @param request_data
	 */
	public Boolean checkSignature(JSONObject request_data) {
		JSONObject certificateSignature = request_data.getJSONObject("certificateSignature");
		String signature = certificateSignature.getString("signature");
		return verify(request_data.toString(),signature);
	}
	
	/**
     *  对数据进行签名
     * @param orgin 原文
     * @return 签名值
     */
    public byte[] signData(String orgin) {
        try {
            Resource resource = unionPayUCSPProperties.getSignature().getPrivateKey();
            char[] charPassword = unionPayUCSPProperties.getSignature().getPassword().toCharArray();
            String alias = "";
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            keyStore.load(resource.getInputStream(),charPassword);
            Enumeration<String> e = keyStore.aliases();
            if (e.hasMoreElements()){
                alias = (String)e.nextElement();
            }
            RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) keyStore.getKey(alias, charPassword);
            Signature sign = Signature.getInstance("SHA256WithRSA");
            sign.initSign(privateKey);
            byte[] bysData = orgin.getBytes(StandardCharsets.UTF_8);
            sign.update(bysData);
            byte[] signByte = sign.sign();
            return signByte;
        }catch (Exception e){
            throw new BizException(ResultCode.CALL.build(1),"签名异常");
        }
    }

    /**
     * 验证签名
     * @param plainText 原文
     * @param signature 签名
     * @return 是否验签通过
     */
    public boolean verify(String plainText, String signature) {
        try {
            Resource publicKeyResource = unionPayUCSPProperties.getSignature().getPublicKey();
            CertificateFactory certificatefactory = CertificateFactory.getInstance(X509);
            X509Certificate cert = (X509Certificate) certificatefactory.generateCertificate(publicKeyResource.getInputStream());
            PublicKey publicKey = cert.getPublicKey();
            Signature publicSignature  = Signature.getInstance("SHA1withRSA");
            publicSignature.initVerify(publicKey);
            publicSignature.update(plainText.getBytes(StandardCharsets.UTF_8));

            byte[] signatureBytes = Base64.getDecoder().decode(signature);
            return publicSignature.verify(signatureBytes);
        }catch (Exception e){
            throw new BizException(ResultCode.CALL.build(2),"验签异常");
        }
    }
	
	/**
	 * 解密数据
	 * @param encryptData 待解密字符串
	 * @return
	 */
	public String decrypt(String encryptData){
		try {
			Encrypt encrypt = unionPayUCSPProperties.getEncrypt();
			Resource privateKeyResource = encrypt.getPrivateKey();
			 char[] charPassword = encrypt.getPassword().toCharArray();
			 String alias = "";
	            KeyStore keyStore = KeyStore.getInstance("PKCS12");
	            keyStore.load(privateKeyResource.getInputStream(),charPassword);
	            Enumeration<String> e = keyStore.aliases();
	            if (e.hasMoreElements()){
	                alias = (String)e.nextElement();
	            }
	            RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) keyStore.getKey(alias, charPassword);
	            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
	    		cipher.init(Cipher.DECRYPT_MODE, privateKey);
	    		byte[] deBytes = cipher.doFinal(Base64.getDecoder().decode(encryptData));
	    		return Base64.getEncoder().encodeToString(deBytes);
		} catch (Exception e) {
			throw new BizException(ResultCode.CALL.build(3),"解密失败");
		}
	}
	
	/**
     * 加密数据
     * @param orgin 待加密原始数据
     * @return
     */
    String encrypt(String orgin) {
        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            Encrypt encrypt = unionPayUCSPProperties.getEncrypt();
            CertificateFactory certificatefactory = CertificateFactory.getInstance(X509);
            Certificate cert = certificatefactory.generateCertificate(encrypt.getPublicKey().getInputStream());
            PublicKey publicKey = cert.getPublicKey();

            Cipher tcsCipher = Cipher.getInstance(publicKey.getAlgorithm());//通过公钥的加密算法获取加解密实例

            tcsCipher.init(Cipher.ENCRYPT_MODE, publicKey);//通过公钥初始化实例
            byte[] encryptData = tcsCipher.doFinal(orgin.getBytes());
            return Base64.getEncoder().encodeToString(encryptData);/* 要加密的字符串进行编码 */
        } catch (Exception e) {
            throw new BizException(ResultCode.CALL.build(4),"加密失败");
        }
    }
	
//	public static String sign(String data,String appPrivateKeyPem) throws Exception {
//		MessageDigest mgd;
//		byte[] signed = null;
//		mgd = MessageDigest.getInstance("SHA-256");
//		mgd.update(data.getBytes());
//		byte [] hashdata = mgd.digest();
//		Signature signature = Signature.getInstance("NONEWithRSA");
//		PrivateKey priKey = getPrivateKey(appPrivateKeyPem);
//		signature.initSign(priKey);
//		signature.update(hashdata);
//		signed = signature.sign();
//		return new BASE64Encoder().encode(signed);
//	}
//	
//	//验签
//	public static boolean verify(byte[] data, String publicKey, String sign)throws Exception {
//		byte[] keyBytes = new BASE64Decoder().decodeBuffer(publicKey);
//		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
//		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//		PublicKey publicK = keyFactory.generatePublic(keySpec);
//		Signature signature = Signature.getInstance("NONEWithRSA");
//		signature.initVerify(publicK);
//		signature.update(data);
//		return signature.verify(new BASE64Decoder().decodeBuffer(sign));
//	}
//	
//	public static PrivateKey getPrivateKey(String key) throws Exception {
//        byte[] keyBytes;
//        keyBytes = (new BASE64Decoder()).decodeBuffer(key);
//		  PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
//
//        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
//        
//        return privateKey;
//	}
	
//	public static void main(String[] args) throws Exception {
//
//    	String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCn6uvp384qRQ+5QyiV3u54I8CGnIt644abvjLYFGhZOjZTHTu7uPhfYirLEcgojwXrUJ7eUeDmbQ825AsM3K5L3FkzCb7JUnp9oOuZ/vzyrC3UeKZ2fUl+J77EQC5rCpnK9A9iiw3nc+erL/ejD1YegTwqx2ZPnqhTVd9RuS8lI6U59uiOq/XMYOFcgwqLOe81U0WVD7IqE34AzuiS3flm5eskpVeHHTcUPwu7BKdgrRYvrrKBpbmF7K2kjYdsFXzRGwq1bg6A4EO9+NHi8VvkA4WtWh89MmzNh71FvabvZxfU3iRRrI/bMpepuuHJlG9nx5gvKD5KHeQB+PsadGONAgMBAAECggEAG4aH64uTaRxvCmh247JqlukNa0OIHbnkW+1euksGG/JN62v0Wb5lgIVADI+6puNjDgLmN/1mB3/DKbVSFmaqb6cMPDCRxMCvcZ6KYHELF+Cflp+8cdnxzStIuzTmJwfS1BET4Ix42AMI6+fuCR2/eTqoGT8ch1qzrw15kRTxJH4iVBRtS4xQBKV5EVI82UtViEMvQpx2uo6JeAUGE8Or5c1GU4Rvt2NVWZ4NEn6HuS9WsjeYCWL6eLwD+c7LiAGVdWFI9d1yJZtTtDrzwIkefq3K/mDt0jnC0TRHEYeJQSvfuupV1ylkXIuYmxDXexKuHUuhBHmGmv41bF5sngvJoQKBgQDYJzDbs91lNwnIxUoUR7tH4YbcMAjFc9QHIRiwmd9ULkMdgOdsF2yP0FgQx36LsTXX8AMntuAQpnMytJc+pfpcbtFLyxzZiXJZYVRSSHrQGP272szm4IxhmPhlAz4LksETIXnSoVNITPxPkof0oJA56pEs+KbYDDexIuoW98R3dQKBgQDG32EZgj36VutMYIbPDS7aVP8n8KBtDpPR79UloQW0/C0tjuWQ+9qTXmo3cPi/HV2nNEvoj78DvdbsJ8awUVCi7DIA5UF0kO1xgmWKmdi5BrVlQg00F75lfvokVwZqU+yCHsosDN9/mpq4HvsCawtIJe5sKeMAw3fDVexWuF/QuQKBgQCvQx+/lNi4H+dkDmwhg4QcJYZm9N+30lIiMbjGQQ2vQQ+UVZfPsjKJbYJqoIdAF0E0RN0aD5MgjQYtH/beilA1MHmt/hP3YxX/2QY47aH/J7Rc5G1t6raI0DLgHL/rPGQm8ebIXZycrCeNEaABP0uSWlq6XydRWJ6zlz69vspjnQKBgH4pqAfuwDLYgV1qvxsLWfXYhiZoWN3WqaA9bhL5HA29DUwhozFfFUL4WpnhaWyUzJ0OaDmZN6y/+mDGux2P+H/jJ7W5utSgPIIOHyzWfM6kmt8qEAZEKd1puHblXoSFyTyjG87mO8NP6Wd0//iAwB99MMwdpo0NdCTPladOQDrBAoGBAIZzWkBMv3qiT+Wm23fdll/pRhTcnRokSphYPHBxy3ZiKUBqdArQuGmbxv4i1z6JrXc7izjMIMaSVnrcUIpzRo0ZM9zRaj03itlYlz3cYtpp8vTjhWEhP39Qd+1QlqdNa1+ltCy7inrvUvB4oCUaJbj6fXBJPxjbX8glHhvbAqGT";
//    	String data =  "J1lSJt0ifvUa2EjbiMBePUVrt/SpvrpoKbmcQD3IaegZqt27wK5qudQz63XVAPec85kAQN5rQSAgIY8nY7EniZ8swpZ6rQLgRayNDRLgqdOR3rlEb7UTp8JoSx6ydaJ6H+BV7XDCAnmzINZw0wQ9ib+tRk0Ic9EPmCZSWXCTYjHi2ll/fP3VjoXOXE94HIXh2diHPqlbNJ4uAKTc0edyl4vhbUAd6uVWZnrzonkueHiOQnAsA0e8nZXf3zllyzXQeeSiAOpR9HJq3nctWG60KMrSu5vKS9Riv5fBRFp1bgVP/LUhYVYLupvd7oW1YuLX5AkTYmC49P1rNiwTIjLw/A==";// encryptByPublicKey("123321", getPublicKeyByString(pubKey));
//    	String dec = decrypt(new BASE64Decoder().decodeBuffer(data), priKey);
//		System.out.println(dec);
//
//	}
}
